// RingBuffer.h - ring (round robin) buffer interface

#ifndef RINGBUFFER_H_
#define RINGBUFFER_H_

#include <string.h>
#include "pthread.h"

class RingBuffer;

typedef struct _threadData {
    RingBuffer*         pRingBuffer;
    bool                bSaveToFile;
} ThreadData_Reading;


class RingBuffer
{
public:
     RingBuffer(int sizeBytes = 0);
     ~RingBuffer();

     int Write(unsigned char *dataPtr, int numBytes);
     int Read(unsigned char* dataPtr, int numBytes);
     int ReadPrevBuffer(unsigned char *dataPtr, int numBytes);
     int StartReadingThread();
     int ResumeReading();
     int PauseReading();
     int Exit();

     bool Empty(void);
     int GetSize();
     void InitSize( int size);
     void InitBufferFileName( const char* pszFileName) { strcpy( m_szBufferFileName, pszFileName); }
     char* GetBufferFileName() { return m_szBufferFileName; }
     void SetReadSize( int nReadSize) { m_nReadSize = nReadSize; }
     int  GetReadSize() { return m_nReadSize; }
     void ShowBuffer( int nAction);
     void SignalReadingThreadCreated();

private:
     int WriteBuffer(unsigned char *ptrTo, int& nWritePos, unsigned char *&ptrFrom, int& nWriteLen);

private:
     unsigned char * m_pData;
     int m_size;
     int m_readPos;
     int m_writePos;
     bool m_bBufferLooped;
     bool m_bReadingStarted;
     bool m_bExit;
     int m_nReadSize;
     char m_szBufferFileName[100];

     pthread_mutex_t m_ring_buffer_mutex;
     pthread_cond_t m_condSpaceAvailable;
     pthread_cond_t m_condReading;
     pthread_cond_t m_condReadingThreadCreated;

     pthread_t m_threadReading;
     ThreadData_Reading m_threaddataReading;

     static void* ThreadWorker_Reading(void *data);

};

#endif /* RINGBUFFER_H_ */
